package cn.kust.clock.service.impl;

import cn.kust.clock.mapper.*;
import cn.kust.clock.pojo.dto.TravelsOverDTO;
import cn.kust.clock.pojo.entity.Clock;
import cn.kust.clock.pojo.entity.Image;
import cn.kust.clock.pojo.entity.Travels;
import cn.kust.clock.pojo.vo.ClockVO;
import cn.kust.clock.pojo.vo.TravelsDetailVO;
import cn.kust.clock.pojo.vo.TravelsVO;

import cn.kust.clock.service.TravelsService;
import cn.kust.clock.wrapper.ClockWrapper;
import cn.kust.clock.wrapper.TravelsWrapper;
import cn.kust.microtourismcommon.pojo.dto.UserIdDTO;
import cn.kust.microtourismcommon.pojo.dto.UserNameAvatar;
import cn.kust.microtourismcommon.remote.ServiceUserCenterClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author bjs
 * @date 2022/7/27 0027  15:50
 **/
@Slf4j
@Service
public class TravelsServiceImpl implements TravelsService {

    /**
     * mapper类
     */
    @Autowired(required = false)
    private ServiceUserCenterClient userClient;

    @Autowired
    private LikeMapper likeMapper;

    @Autowired
    private TravelsMapper travelsMapper;

    @Autowired
    private ClockMapper clockMapper;

    @Autowired
    private ImageMapper imageMapper;

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private CollectionMapper collectionMapper;

    /**
     * wrapper类
     */
    @Autowired
    private ClockWrapper clockWrapper;

    @Autowired
    private TravelsWrapper travelsWrapper;
    /**
     *
     * @param page 页数
     * @return 微路线的列表
     */
    @Override
    public List<TravelsVO> travelsList(Integer page) throws Exception {
        //1.调用LikeMapper去获取游记id列表
        List<Long> travelsIdList = likeMapper.selectHotOfHighLike(2, page);
        //2.调用TravelsMapper根据id列表去获取信息
        List<Travels> travelsList = travelsMapper.selectBatchIds(travelsIdList);
        //2.1创建返回的数据列表
        List<TravelsVO> travelsVOList = new ArrayList<>();
        UserIdDTO userIdDTO = new UserIdDTO();
        List<Long> userIdList =new ArrayList<>();
        //2.2将userId遍历出来、
        for (Travels travels : travelsList) {
            userIdList.add(travels.getUserId());
        }
        userIdDTO.setUserIdList(userIdList);
        Object data = userClient.getUserNameAvatarList(userIdDTO).getData();
        //3.获取游记对应的点赞数
        for (Travels travels : travelsList) {
            int i = 0;
            //3.1获取游记对应的点赞数
            Integer likeNum = likeMapper.getLikeCountByTypeAndTypeId(2, travels.getId());
            //3.2封装对象
            TravelsVO travelsVO = new TravelsVO(travels,((List<?>) data).get(i++),likeNum);
            travelsVOList.add(travelsVO);
        }
        return travelsVOList;
    }

    /**
     *
     * @param id 微路线id
     * @return 微路线的详细信息
     */
    @Override
    public TravelsDetailVO travels(Long id) throws Exception {
        //1.调用TravelsMapper获取对应的微路线
        Travels travels = travelsMapper.selectById(id);
        //2.处理字符串获取他打卡的id列表
        String[] split = travels.getClockIdList().split(",");
        List<Long> clockIdList = new ArrayList<>();
        for (String s : split) {
            clockIdList.add(Long.valueOf(s));
        }
        //3.调用ClockMapper去查询微记列表、
        List<Clock> clockList = clockMapper.selectBatchIds(clockIdList);
        //3.1获取对应userid的用户信息
        UserNameAvatar user = (UserNameAvatar) userClient.getUserNameAvatarById(travels.getUserId()).getData();
        //4.将Clock封装成对应VO
        List<ClockVO> clockVOList = new ArrayList<>();
        for (Clock clock : clockList) {
            HashMap<String,Object> rule = new HashMap<>();
            rule.put("clock_sort_id",clock.getId());
            //4.1获取当前微记一张图片作为背景
            List<Image> images = imageMapper.selectByMap(rule);
            //4.2获取当前微记的点赞数
            Integer likeNum = likeMapper.getLikeCountByTypeAndTypeId(1, clock.getId());
            //4.3创建对应VO对象
            ClockVO clockVO = new ClockVO(clock,null,images.get(0),likeNum);
            //4.4将VO对象加入VO数组中
            clockVOList.add(clockVO);
            //4.5将map中数据清空
            rule.clear();
        }
        //5.获取对应的点赞数
        Integer likeNum = likeMapper.getLikeCountByTypeAndTypeId(2, id);
        //6.获取对应的评论数
        Integer commentNum = commentMapper.getCommentCountByTravelsId(id);
        TravelsDetailVO travelsDetailVO = new TravelsDetailVO(travels,clockVOList,user,likeNum,commentNum);
        return travelsDetailVO;
    }

    /**
     *
     * @param userId 用户id
     * @return 个人的微路线的列表
     */
    @Override
    public List<TravelsVO> myselfTravelsList(Long userId) throws Exception {
        //1.获取对应userid的用户信息
        //2.写查询规则
        HashMap<String,Object> rule = new HashMap<>();
        rule.put("user_id",userId);
        rule.put("status",1);
        //3.通过条件去查询的对应的数据
        List<Travels> travelsList = travelsMapper.selectByMap(rule);
        //3.1远程调用得到用户信息
        UserNameAvatar user = (UserNameAvatar) userClient.getUserNameAvatarById(travelsList.get(0).getUserId()).getData();
        //4.创建List<TravelsVO>
        List<TravelsVO> travelsVOList = new ArrayList<>();
        //5.查询每条的Travels的点赞数
        for (Travels travels : travelsList) {
            Integer likeNum = likeMapper.getLikeCountByTypeAndTypeId(2, travels.getId());
            //5.将travels进行封装
            TravelsVO travelsVO = new TravelsVO(travels,user,likeNum);
            travelsVOList.add(travelsVO);
        }
        return travelsVOList;
    }


    /**
     *
     * @param userId 用户id
     * @return 对应的游记id
     */
    @Override
    public Long begin(Long userId) throws Exception {
        //1.创建一个Travels对象
        Travels travels = new Travels(userId, LocalDateTime.now());
        //2.通过mapper去增加数据
        int insert = travelsMapper.insert(travels);
        //3.返回对应的Travels的id
        return travels.getId();
    }


    /**
     *
     * @param travelsOverDTO 前端传过来的from表单
     * @return 受影响的行数
     */
    @Override
    public Integer over(TravelsOverDTO travelsOverDTO,Integer judge) throws Exception {
        //1.通过状态区判断用户是否需要创建一个游记
        Integer i;
        if(judge == 1){
            //1.1获取开始行程对应的时间
            QueryWrapper<Travels> eq = travelsWrapper.eq("user_id", travelsOverDTO.getUserId())
                    .eq("status", 0);
            Travels travels = travelsMapper.selectOne(eq);
            //1.1将DTO中对应的打卡id列表查询出来封装
            QueryWrapper<Clock> gmt_create = clockWrapper.between("gmt_create", travels.getGmtCreate(), LocalDateTime.now());
            List<Clock> clockList = clockMapper.selectList(gmt_create);
            //1.2将id列表转化为字符串
            String clockIdList = "";
            for (Clock clock : clockList) {
                clockIdList += String.valueOf(clock.getId()) + ",";
            }
            //1.3创建一个游记的对象
            travels.setClockIdList(clockIdList);
            travels.setStatus(1);
            travels.setTitle(travelsOverDTO.getTitle());
            travels.setDescription(travelsOverDTO.getDescription());
            travels.setCover(travelsOverDTO.getCover());
            travels.setGmtModified(LocalDateTime.now());
            //1.4将游记对应的数据库进行更新
            i = travelsMapper.updateById(travels);
        }else{
            QueryWrapper<Travels> eq1 = travelsWrapper.eq("user_id", travelsOverDTO.getUserId())
                    .eq("status", 0);
            i = travelsMapper.delete(eq1);
        }
        return i;
    }

    /**
     *
     * @param userId 用户id
     * @return 收藏的游记
     * @throws Exception
     */
    @Override
    public List<TravelsVO> collectTravelsList(Long userId) throws Exception {
        //1.调用collectionMapper获取idlist
        List<Long> travelsIdList = collectionMapper.selectClockIdListByUserIdAndType(userId);
        //2.调用TravelsMapper根据id列表去获取信息
        List<Travels> travelsList = travelsMapper.selectBatchIds(travelsIdList);

        List<TravelsVO> travelsVOList = new ArrayList<>();
        UserIdDTO userIdDTO = new UserIdDTO();
        List<Long> userIdList =new ArrayList<>();
        //2.2将userId遍历出来、
        for (Travels travels : travelsList) {
            userIdList.add(travels.getUserId());
        }
        userIdDTO.setUserIdList(userIdList);
        Object data = userClient.getUserNameAvatarList(userIdDTO).getData();

        //3.获取游记对应的点赞数
        for (Travels travels : travelsList) {
            int i = 0;
            //3.1获取游记对应的点赞数
            Integer likeNum = likeMapper.getLikeCountByTypeAndTypeId(2, travels.getId());
            //3.2封装对象
            TravelsVO travelsVO = new TravelsVO(travels,((List<?>) data).get(i++),likeNum);
            travelsVOList.add(travelsVO);
        }
        return travelsVOList;
    }


}
